package com.oss.service.oss;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oss.common.BaseResponse;
import com.oss.dto.oss.importLog.DownloadDto;
import com.oss.dto.oss.importLog.DownloadErrorDto;
import com.oss.dto.oss.importLog.PageDto;
import com.oss.entity.oss.ImportLog;
import com.oss.entity.oss.Student;
import com.oss.enums.IsDeletedEnum;
import com.oss.mapper.oss.ImportLogMapper;
import com.oss.service.system.UserService;
import com.oss.util.SnowFlakeUtil;
import com.oss.vo.oss.capital.CapitalManageVO;
import com.oss.vo.oss.importLog.ImportLogVO;
import com.oss.vo.oss.student.StudentVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ImportLogService extends ServiceImpl<ImportLogMapper, ImportLog> {
    @Autowired
    StudentService studentService;
    @Autowired
    UserService userService;
    @Value("${uploadPath}")
    String uploadPath;
    @Value("${downloadUrl}")
    String downloadUrl;
    @Autowired
    DataImportService dataImportService;
    @Autowired
    ImportLogService importLogService;

    public void add(ImportLog entity){
        LambdaQueryWrapper<ImportLog> wrapper = new LambdaQueryWrapper<ImportLog>();
        wrapper.eq(ImportLog::getIsDeleted, IsDeletedEnum.NO.getFlag());
        wrapper.eq(ImportLog::getTradeDate, entity.getTradeDate());
        long count = this.count(wrapper);
        // 这一天已有失败信息 , 删除已有的失败信息 , 再去新增
        if (count > 0) {
            LambdaUpdateWrapper<ImportLog> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(ImportLog::getIsDeleted, IsDeletedEnum.NO.getFlag());
            updateWrapper.eq(ImportLog::getTradeDate, entity.getTradeDate());
            updateWrapper.eq(ImportLog::getStudentID, entity.getStudentID());
            updateWrapper.set(ImportLog::getIsDeleted,IsDeletedEnum.YES.getFlag());
            this.update(null,updateWrapper);
        }
        entity.setId(SnowFlakeUtil.getID());
        this.save(entity);
    }

    public IPage<ImportLogVO> selectByPage(PageDto dto) {
        LambdaQueryWrapper<ImportLog> wrapper = new LambdaQueryWrapper<ImportLog>();
        wrapper.eq(ImportLog::getIsDeleted, IsDeletedEnum.NO.getFlag());
        wrapper.eq(StringUtils.isNotBlank(dto.getStudentID()),ImportLog::getStudentID, dto.getStudentID());
        wrapper.eq(dto.getTradeDate() != null,ImportLog::getTradeDate, dto.getTradeDate());
        wrapper.eq(dto.getStatus() != null,ImportLog::getStatus, dto.getStatus());
        IPage<ImportLog> page = this.page(new Page<>(dto.getPageNo(), dto.getPageSize()), wrapper);
        Map<String,String> userMap = new HashMap<>();
        Map<String, StudentVO> studentMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(page.getRecords())) {
            // 获取创建人和修改人ID
            Set<String> ids = page.getRecords().stream().map(ImportLog::getCreatorId).collect(Collectors.toSet());
            ids.addAll(page.getRecords().stream().map(ImportLog::getUpdatorId).collect(Collectors.toSet()));
            userMap = userService.selectByIds(ids);
            Set<String> sids = page.getRecords().stream().map(ImportLog::getStudentID).collect(Collectors.toSet());
            studentMap = studentService.selectByIDs(sids);
        }
        Map<String, StudentVO> finalStudentMap = studentMap;
        Map<String, String> finalUserMap = userMap;
        return page.convert(entity->{
            ImportLogVO vo = new ImportLogVO();
            BeanUtils.copyProperties(entity,vo);
            if (finalStudentMap.containsKey(entity.getStudentID())){
                StudentVO studentVO = finalStudentMap.get(entity.getStudentID());
                vo.setStudentID(studentVO.getId());
                vo.setStudentPhone(studentVO.getPhone());
                vo.setStudentName(studentVO.getName());
                vo.setStudentWechatID(studentVO.getWechatID());
                vo.setStudentAccount(studentVO.getAccount());
                vo.setCode(studentVO.getCode());
                String filePath = uploadPath+studentVO.getAccount() + "_" + entity.getTradeDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+".xls";
                vo.setFilePath(filePath);
            }
            vo.setCreatorName(finalUserMap.get(entity.getCreatorId()));
            vo.setUpdatorName(finalUserMap.get(entity.getUpdatorId()));
            return vo;
        });
    }

    public BaseResponse download(DownloadDto dto) throws Exception {
        if (dto.getTradeDate().getDayOfWeek() == DayOfWeek.SATURDAY) {
            return BaseResponse.error(dto.getTradeDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+" , 当前日期是周六, 非交易日无数据下载");
        } else if (dto.getTradeDate().getDayOfWeek() == DayOfWeek.SUNDAY) {
            return BaseResponse.error(dto.getTradeDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+" , 当前日期是周日, 非交易日无数据下载");
        }
        Student student = studentService.getById(dto.getStudentID());
        if (student == null) {
            throw new RuntimeException("学员不存在,学员ID="+dto.getStudentID());
        }
        String filePath = student.getAccount() + "_" + dto.getTradeDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+".xls";
        File file = new File(uploadPath + filePath);
        // 文件存在
        if (file.exists()) {
            return BaseResponse.success(student.getName()+"此学员在"+dto.getTradeDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+"号的文件已存在 , 不需要重新下载");
        } else {
            Map parameterMap = new HashMap<>();
            parameterMap.put("Account", student.getAccount());
            parameterMap.put("Password", student.getPassword());
            parameterMap.put("QueryDate", dto.getTradeDate().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
            parameterMap.put("byType", "");
            // 待插入日志对象
            ImportLog entity = new ImportLog();
            entity.setStudentID(student.getId());
            entity.setTradeDate(dto.getTradeDate());
            String result = "";
            try{
                // 发送http请求
                result = HttpUtil.post(downloadUrl, JSON.toJSONString(parameterMap));
            } finally {
                if (StringUtils.isEmpty(result)) {
                    entity.setStatus(-1);
                    entity.setMessage("下载服务未启动");
                    importLogService.add(entity);
                } else {
                    JSONObject resultObject = JSON.parseObject(result);
                    if (resultObject.containsKey("code")) {
                        String code = resultObject.getString("code");
                        if ("1".equals(code)) {
                            JSONObject dataObject = resultObject.getJSONObject("data");
                            String FilePath = dataObject.getString("FilePath");
                            File downloadFile = new File(FilePath);
                            if (!downloadFile.exists()) {
                                entity.setStatus(-1);
                                entity.setMessage("文件不存在,"+result);
                                importLogService.add(entity);
                                throw new RuntimeException("文件不存在"+FilePath);
                            } else {
                                entity.setStatus(1);
                                importLogService.add(entity);
                                dataImportService.importTradeInfo(new FileInputStream(downloadFile),student.getAccount());
                            }
                        } else {
                            entity.setStatus(-1);
                            entity.setMessage(result);
                            importLogService.add(entity);
                            throw new RuntimeException("文件下载异常, "+resultObject.getString("message"));
                        }
                    } else {
                        entity.setStatus(-1);
                        entity.setMessage(result);
                        importLogService.add(entity);
                        throw new RuntimeException("文件下载异常 , 请重试......");
                    }
                }

            }
        }
        return BaseResponse.success("操作成功");
    }

    public BaseResponse downloadErrorDate(DownloadErrorDto dto) {
        LambdaQueryWrapper<ImportLog> wrapper = new LambdaQueryWrapper<ImportLog>();
        wrapper.eq(ImportLog::getIsDeleted, IsDeletedEnum.NO.getFlag());
        wrapper.eq(ImportLog::getTradeDate, dto.getTradeDate());
        wrapper.eq(ImportLog::getStatus, -1);
        // 查询指定日期中 , 下载失败的数据
        List<ImportLog> list = this.list(wrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            for (ImportLog item : list) {
                DownloadDto downloadDto = new DownloadDto();
                downloadDto.setTradeDate(dto.getTradeDate());
                downloadDto.setStudentID(item.getStudentID());
                try {
                    download(downloadDto);
                } catch (Exception e) {
                    log.error("重新下载指定日期的失败数据时异常 , 学员ID="+item.getId() + ";异常信息=" +e.getMessage());
                }
            }
            return BaseResponse.success("文件下载中");
        } else {
            return BaseResponse.success("选择的日期中没有下载失败的数据");
        }
    }
}